package com.genersoft.iot.vmp.utils;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.*;

public class AliOSSUtil {
    private static final Logger logger = LoggerFactory.getLogger(AliOSSUtil.class);
    // endpoint
    private static final String endpoint = "oss-cn-shenzhen.aliyuncs.com";
    // accessKey
    //private static final String accessKeyId = "LTAI5tLycLEmNgH3dE9Ykc4e";
    private static final String accessKeyId = "LTAI4GKTrjnvM94CoLLqLXu5";
    //accessKeySecret
//    private static final String accessKeySecret = "C3n2ZF3EfwGfE6bicK6REf50K4de75";
    private static final String accessKeySecret = "x4jPafwbLyOPWV4EThVYgHLThTlzNt";
    // 空间
//    private static final String bucketName = "rox";
    private static final String bucketName = "hndianhuifile";
    // 文件存储目录
//    private static final String filedir = "filedata/fileupload";
    private static final String filedir = "edianhui/gb/alarm/";

    private OSSClient ossClient;

    public AliOSSUtil() {
        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }

    /**
     * 初始化
     */
    public void init() {
        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }

    /**
     * 销毁
     */
    public void destory() {
        ossClient.shutdown();
    }

    /**
     * 上传图片
     *
     * @param path
     */
    public String uploadByPath(String path) {
        return this.uploadByPath(path, null);
    }

    /**
     * @param path
     * @param fileStoragePath
     * @return
     */
    public String uploadByPath(String path, String fileStoragePath) {
        if (null == fileStoragePath) {
            fileStoragePath = filedir;
        }
        File fileOnServer = new File(path);
        String originalFilename = path.substring(path.lastIndexOf("/") + 1);

        //重新命名
        originalFilename = this.generateFileName(originalFilename);

        FileInputStream fin;
        try {
            fin = new FileInputStream(fileOnServer);
            this.uploadFile2OSS(fin, originalFilename, fileStoragePath);

            return originalFilename;
        } catch (FileNotFoundException e) {
            logger.error(e.toString());
            return null;
        }
    }

    public String uploadByPath(String path, String fileName, String fileStoragePath) {
        if (null == fileStoragePath) {
            fileStoragePath = filedir;
        }
        File fileOnServer = new File(path);
        String originalFilename = path.substring(path.lastIndexOf("/") + 1);

        //重新命名
        originalFilename = this.generateFileName(originalFilename);

        FileInputStream fin;
        try {
            fin = new FileInputStream(fileOnServer);
            this.uploadFile2OSS(fin, path + fileName, fileStoragePath);

            return fileName;
        } catch (FileNotFoundException e) {
            logger.error(e.toString());
            return null;
        }
    }

    /**
     * 上传图片文件
     *
     * @param file
     * @return
     */
    public String uploadImg2OSS(MultipartFile file) {
        return uploadImg2OSS(file, null);
    }

    /**
     * 上传图片文件 + 路径
     *
     * @param file
     * @param fileStoragePath
     * @return
     */
    public String uploadImg2OSS(MultipartFile file, String fileStoragePath) {
        if (null == fileStoragePath) {
            fileStoragePath = filedir;
        }
        fileStoragePath = fileStoragePath + DateUtil.formatDate(new Date(),"yyyyMMdd")+"/";
        if (file.getSize() > 500 * 1024 * 1024) {
            logger.error("上传图片大小不能超过500M！");
        }
        String originalFilename = file.getOriginalFilename();

        String name = this.generateFileName(originalFilename);
 //       String name = originalFilename;
        try {
            InputStream inputStream = file.getInputStream();
            this.uploadFile2OSS(inputStream, name, fileStoragePath);
            return name;
        } catch (Exception e) {
            logger.error(e.toString());
            return null;
        }
    }

    private String generateFileName(String originalFilename) {
        String generationFileName= DateUtil.formatDate(new Date(),"yyyyMMddHHmmss")+"_"+ UUID.randomUUID().toString().replaceAll("-", "")+"_"+new Random().nextInt(10000);

        if (StringUtils.isEmpty(originalFilename)) {
            return generationFileName+".jpg";
        }
        String extendName = originalFilename.substring(originalFilename.lastIndexOf("."));
//        String fileName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
        String name = generationFileName + extendName;

        return name;
    }

    /**
     * 上传图片并压缩图片
     *
     * @param file
     * @param fileStoragePath
     * @param fileCompressStoragePath
     * @return
     */
    public Map<String, String> uploadImg2OSS(MultipartFile file, String fileStoragePath, String fileCompressStoragePath) throws IOException {
        String imgName = uploadImg2OSS(file, fileStoragePath);

        Map<String, String> jsonObject = new HashMap<String, String>();
        jsonObject.put("imgName", imgName);
        if (fileCompressStoragePath != null) {
            //压缩图片
            String extendName = imgName.substring(imgName.lastIndexOf("."));
            String fileName = imgName.substring(0, imgName.lastIndexOf("."));
            String imgCompressName = fileName + "_compress" + extendName;
            jsonObject.put("imgCompressName", imgCompressName);
            try {
                BufferedImage bufImg = ImageIO.read(file.getInputStream());//把图片读入到内存中
                //压缩代码
//                bufImg = Thumbnails.of(bufImg).size(bufImg.getWidth(), bufImg.getHeight()).outputQuality(0.9).asBufferedImage();

                //转成inputStream
                ByteArrayOutputStream bos = new ByteArrayOutputStream();//存储图片文件byte数组
//            ImageOutputStream ios = ImageIO.createImageOutputStream(bos);
//            ImageIO.write(bufImg, "jpg", ios); //图片写入到 ImageOutputStream

                InputStream inputStream = new ByteArrayInputStream(bos.toByteArray());
                this.uploadFile2OSS(inputStream, imgCompressName, fileCompressStoragePath);

            } catch (IOException e) {
                logger.error(e.toString());
            }

        }

        return jsonObject;
    }

    /**
     * 上传文件
     *
     * @param file
     * @param fileUploadPath
     * @return
     * @throws IOException
     */
    public String uploadFile2OSS(File file, String fileUploadPath) throws IOException {

        if (null == fileUploadPath) {
            fileUploadPath = filedir;
        }

        fileUploadPath = fileUploadPath + DateUtil.formatDate(new Date(),"yyyyMMdd")+"/";
        try {
            String name = null;//file.getName();
            FileInputStream inputStream = new FileInputStream(file);
            return this.uploadFile2OSS(inputStream, null, fileUploadPath);
           // return name;
        } catch (Exception e) {
            logger.error(e.toString());
            return null;
        }
    }

    /**
     * 上传到OSS服务器 如果同名文件会覆盖服务器上的
     *
     * @param instream 文件流
     * @param fileName 文件名称 包括后缀名
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public String uploadFile2OSS(InputStream instream, String fileName, String fileStoragePath) {
        if(StringUtils.isEmpty(fileName)){
            fileName = this.generateFileName(fileName);
        }
        if (null == fileStoragePath) {
            fileStoragePath = filedir;
        }
        fileStoragePath = fileStoragePath +DateUtil.formatDate(new Date(),"yyyyMMdd")+"/";
        String ret = "";
        try {
            // 创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf(".")+ 1)));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);
            // 上传文件
            PutObjectResult putResult = ossClient.putObject(bucketName, fileStoragePath + fileName, instream, objectMetadata);
            ret = putResult.getETag();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        logger.error("upload finished");
        return fileName;
    }


    /**
     * 获得图片路径
     *
     * @param fileUrl
     * @return
     */
    public String getImgUrl(String fileUrl) {
        return getImgUrl(null, fileUrl);
    }

    public String getImgUrl(String fileUrl, String fileStoragePath) {
        if (null == fileStoragePath) {
            fileStoragePath = this.filedir;
        }
        fileStoragePath = fileStoragePath + DateUtil.formatDate(new Date(),"yyyyMMdd")+"/";

        if (!StringUtils.isEmpty(fileUrl)) {
            String[] split = fileUrl.split("/");
            String resultUrl=this.getUrl(fileStoragePath + split[split.length - 1]);

            if(resultUrl.contains("?")){//去除url中“？”后面的内容
                resultUrl=resultUrl.substring(0,resultUrl.lastIndexOf("?"));
            }
            return resultUrl;
        }
        return null;
    }

    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param filenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String filenameExtension) {
        if (filenameExtension.equalsIgnoreCase("bmp")) {
            return "image/bmp";
        }else if (filenameExtension.equalsIgnoreCase("gif")) {
            return "image/gif";
        }else if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg")
                || filenameExtension.equalsIgnoreCase("png")) {
            return "image/jpeg";
        }else if (filenameExtension.equalsIgnoreCase("html")) {
            return "text/html";
        }else if (filenameExtension.equalsIgnoreCase("txt")) {
            return "text/plain";
        }else if (filenameExtension.equalsIgnoreCase("vsd")) {
            return "application/vnd.visio";
        }else if (filenameExtension.equalsIgnoreCase("pptx")) {
//            return "application/vnd.ms-powerpoint";
            return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
        }else if (filenameExtension.equalsIgnoreCase("ppt")) {
            return "application/vnd.ms-powerpoint";
//            return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
        }else if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) {
            return "application/msword";
        }else if (filenameExtension.equalsIgnoreCase("xml")) {
            return "text/xml";
        }else if (filenameExtension.equalsIgnoreCase("mp4")) {
            return "video/mp4";
        }else if (filenameExtension.equalsIgnoreCase("pdf")) {
            return "application/pdf";
        }
        return "image/jpeg";
    }

    /**
     * 获得url链接
     *
     * @param key
     * @return
     */
    public String getUrl(String key) {
        // 设置URL过期时间为10年 3600l* 1000*24*365*10
        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
        if (url != null) {
            return url.toString();
        }
        return null;
    }

    /**
     * 将base64字符串，生成文件
     */
    public static InputStream convertBase64ToFile(String fileBase64String) {

        try {
            if(fileBase64String.indexOf("base64,") > 0){
                fileBase64String = fileBase64String.substring(fileBase64String.indexOf("base64,")+7);

            }

//            BASE64Decoder decoder = new BASE64Decoder();
//            byte[] bfile = decoder.decodeBuffer(fileBase64String);
            Base64.Decoder decoder = Base64.getMimeDecoder();
            byte[] bfile = decoder.decode(fileBase64String);

            InputStream inputStream  = new ByteArrayInputStream(bfile);
            return inputStream;
//            file = new File(filePath + File.separator + fileName);
//            fos = new FileOutputStream(file);
//            bos = new BufferedOutputStream(fos);
//            bos.write(bfile);
//            return file;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }



    public static void main(String[] args) {
//           String originalFilename="";
//        String name1="";
//        if (StringUtils.isEmpty(originalFilename)) {
//            name1= new Random().nextInt(10000) +"_"+ System.currentTimeMillis()+".jpg";
//        }
//        String extendName = originalFilename.substring(originalFilename.lastIndexOf("."));
//        String fileName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
//        Random random = new Random();
//        String name = fileName/**+"_"+random.nextInt(10000) +"_"+ System.currentTimeMillis() **/ + extendName;

//        AliOSSUtil ossClient = new AliOSSUtil();
//
////        String url = "/Users/admin/Downloads/WechatIMG343.png";
////        String name = ossClient.uploadByPath(url);
////        String imgUrl = ossClient.getImgUrl(name, null);
//        try {
//
//            String url = ossClient.uploadFile2OSS(new File("C:\\Users\\Administrator\\Desktop\\a.png"),"filedata/fileupload/");
//            String imgUrl = ossClient.getImgUrl(url, "filedata/fileupload/");
//            System.out.println("=============="+imgUrl);
//        }catch (Exception e){
//
//        }


//        MultipartFile file=new File("//Users//admin//Downloads//WechatIMG91.jpeg");
//        String name = ossClient.uploadImg2OSS(file);
//        String imgUrl = ossClient.getImgUrl(name);
//        String[] split = imgUrl.split("\\?");

        String base64Img = "";
        if(base64Img.indexOf("base64,") > 0){
            base64Img = base64Img.substring(base64Img.indexOf("base64,")+7);
            System.out.println(base64Img);
        }
        AliOSSUtil a = new AliOSSUtil();
        String url = a.uploadFile2OSS(AliOSSUtil.convertBase64ToFile(base64Img),null,null) ;
        System.out.println( a.getImgUrl(url, null));

    }

}